using System;
using System.Collections;
using System.Collections.Generic; 
using System.ComponentModel;
using System.Diagnostics; 
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace PropertyGridEx
{

    public class UIStringList
    {
        private List<string> iValue;
        public override string ToString()
        {
            string ret ="";
            string sep=";";

            if (iValue == null)
                return ret;

            for (int n=0; n<iValue.Count; ++n)
            {
                ret += iValue[n];

                if (n < iValue.Count - 1)
                    ret += sep;
            }

            return ret;
        }
         public UIStringList()
         {
             iValue=new List<string>();
         }
         public UIStringList(string str)
         {
             iValue = new List<string>();

		    string[] sep=new string[]{";"};
		    string[] arr=str.Split(sep,System.StringSplitOptions.None);
		    int vege=arr.Length;
		    for (int n=arr.Length-1; n>=0; --n)
		    {
			    if (arr[n]=="")
				    vege--;
			    else
				    break;
		    }
		    for (int n=0; n<vege; ++n)
		    {
			    iValue.Add(arr[n]);
		    }
         }
         public UIStringList(List<string> Text)
         {
             iValue = Text;
         }
        public List<string> Value
        {
            get
            {
                return iValue;
            }
            set
            {
                iValue = value;
            }
        }

        
        public override bool Equals(object obj)
        {
            if (obj is UIStringList)
            {
                UIStringList other = (UIStringList)obj;
                if (other.iValue.Count != iValue.Count)
                    return false;

                for (int n = 0; n < iValue.Count; ++n)
                {
                    if (iValue[n] != other.iValue[n])
                        return false;
                }
                return true;
            }

            return false;
        }
 
    }


        [AttributeUsage(AttributeTargets.Property)]
    public class ListBoxAttribute:Attribute
    {
            private UIStringList iValue;
            public UIStringList Value
        {
            get
            {
                return iValue;
            }
            set
            {
                iValue = value;
            }
        }

        public ListBoxAttribute(UIStringList v)
            {
                iValue=v;
            }
    }



    public class UIListBoxEditor : UITypeEditor
    {
         IWindowsFormsEditorService _wfes = null;
         private ListBox _control  = null;
//         private CustomItemList _list = null;
         public override bool IsDropDownResizable
         {
             get
             {
                 return false;
             }
         }
   
        public override UITypeEditorEditStyle GetEditStyle(
            ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown; 
        }
 
        public override object EditValue(ITypeDescriptorContext context,
                                                       IServiceProvider provider,
                                                       object value)
        {
   
                _wfes = provider.GetService(typeof(IWindowsFormsEditorService)) 
                             as IWindowsFormsEditorService;                                   
 
            if (_wfes == null) { return value; }
//            if (value == null) { return value; }
 
            _control = new ListBox();
            _control.BorderStyle = BorderStyle.None;
            _control.SelectedIndexChanged += new EventHandler(ListItemSelected);

            ListBoxAttribute lattr = (ListBoxAttribute)context.PropertyDescriptor.Attributes[typeof(ListBoxAttribute)];
            List<string> list = lattr.Value.Value;

             for (int i = 0; i < list.Count; i++)
             {
                    _control.Items.Add(list[i]);
             }
             _control.Items.Add(" ");
             _control.Height = 16 * list.Count;// _control.PreferredHeight;
             _control.Items.RemoveAt(_control.Items.Count - 1);

			if (value != null)
                _control.Text= (string)value;
  
            _wfes.DropDownControl(_control);

            if (_control.SelectedIndices.Count==1)
                value = _control.Text;
             
            return value;
        }
       
        private void ListItemSelected(object sender,EventArgs e)
        {
   
           switch (_control.SelectionMode)
           {
               case SelectionMode.MultiExtended:
               case SelectionMode.MultiSimple:
                       break;
               default:
                     _wfes.CloseDropDown();
                   break;
           }

        }
        
    }


















    public class UIListboxEditor : UITypeEditor
    {
        private bool bIsDropDownResizable = false;
        private ListBox oList = new ListBox();
        private object oSelectedValue = null;
        private IWindowsFormsEditorService oEditorService;

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            if (context != null && context.Instance != null)
            {
                UIListboxIsDropDownResizable attribute = (UIListboxIsDropDownResizable)context.PropertyDescriptor.Attributes[typeof(UIListboxIsDropDownResizable)];
                if (attribute != null)
                {
                    bIsDropDownResizable = true;
                }
                return UITypeEditorEditStyle.DropDown;
            }
            return UITypeEditorEditStyle.None;
        }

        public override bool IsDropDownResizable
        {
            get
            {
                return bIsDropDownResizable;
            }
        }

        [RefreshProperties(RefreshProperties.All)]
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            if (context == null || provider == null || context.Instance == null)
            {
                return base.EditValue(provider, value);
            }

            oEditorService = (System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (oEditorService != null)
            {

                // Get the Back reference to the Custom Property
                CustomProperty.CustomPropertyDescriptor oDescriptor = (CustomProperty.CustomPropertyDescriptor)context.PropertyDescriptor;
                CustomProperty cp = (CustomProperty)oDescriptor.CustomProperty;

                // Declare attributes
                UIListboxDatasource datasource;
                UIListboxValueMember valuemember;
                UIListboxDisplayMember displaymember;

                // Get attributes
                datasource = (UIListboxDatasource)context.PropertyDescriptor.Attributes[typeof(UIListboxDatasource)];
                valuemember = (UIListboxValueMember)context.PropertyDescriptor.Attributes[typeof(UIListboxValueMember)];
                displaymember = (UIListboxDisplayMember)context.PropertyDescriptor.Attributes[typeof(UIListboxDisplayMember)];

                oList.BorderStyle = BorderStyle.None;
                oList.IntegralHeight = true;

                if (datasource != null)
                {
                    oList.DataSource = datasource.Value;
                }

                if (displaymember != null)
                {
                    oList.DisplayMember = displaymember.Value;
                }

                if (valuemember != null)
                {
                    oList.ValueMember = valuemember.Value;
                }

                if (value != null)
                {
                    if (value.GetType().Name == "String")
                    {
                        oList.Text = (string)value;
                    }
                    else
                    {
                        oList.SelectedItem = value;
                    }
                }


                oList.SelectedIndexChanged += new System.EventHandler(this.SelectedItem);

                oEditorService.DropDownControl(oList);
                if (oList.SelectedIndices.Count == 1)
                {
                    cp.SelectedItem = oList.SelectedItem;
                    cp.SelectedValue = oSelectedValue;
                    value = oList.Text;
                }
                oEditorService.CloseDropDown();
            }
            else
            {
                return base.EditValue(provider, value);
            }

            return value;

        }

        private void SelectedItem(object sender, EventArgs e)
        {
            if (oEditorService != null)
            {
                if (oList.SelectedValue != null)
                {
                    oSelectedValue = oList.SelectedValue;
                }
                oEditorService.CloseDropDown();
            }
        }

        [AttributeUsage(AttributeTargets.Property)]
        public class UIListboxDatasource : Attribute
        {

            private object oDataSource;
            public UIListboxDatasource(ref object Datasource)
            {
                oDataSource = Datasource;
            }
            public object Value
            {
                get
                {
                    return oDataSource;
                }
            }
        }

        [AttributeUsage(AttributeTargets.Property)]
        public class UIListboxValueMember : Attribute
        {

            private string sValueMember;
            public UIListboxValueMember(string ValueMember)
            {
                sValueMember = ValueMember;
            }
            public string Value
            {
                get
                {
                    return sValueMember;
                }
                set
                {
                    sValueMember = value;
                }
            }
        }

        [AttributeUsage(AttributeTargets.Property)]
        public class UIListboxDisplayMember : Attribute
        {

            private string sDisplayMember;
            public UIListboxDisplayMember(string DisplayMember)
            {
                sDisplayMember = DisplayMember;
            }
            public string Value
            {
                get
                {
                    return sDisplayMember;
                }
                set
                {
                    sDisplayMember = value;
                }
            }

        }

        [AttributeUsage(AttributeTargets.Property)]
        public class UIListboxIsDropDownResizable : Attribute
        {

        }
    }	

}
